﻿using AutoMapper;
using DataServer.ApplicationLib.Controls;
using DataServer.ApplicationLib.Entities;
using DataServer.ApplicationLib.Repositories;
using DataServer.CommonLib.Models.DataConfig;
using Swimj.CommonLib.Base;
using Swimj.DataCore;

namespace DataServer.ApplicationLib.Services
{
    public class DataConfigService : IDataConfigService
    {
        private readonly IDataConfigRepository _dataConfigRepository;
        private readonly IConfigFieldRepository _configFieldRepository;
        private readonly IConfigRuleRepository _configRuleRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMapper _mapper;

        public DataConfigService(IDataConfigRepository dataConfigRepository,
            IConfigFieldRepository configFieldRepository,
            IConfigRuleRepository configRuleRepository,
            IUnitOfWork unitOfWork,
            IMapper mapper)
        {
            _dataConfigRepository = dataConfigRepository;
            _configFieldRepository = configFieldRepository;
            _configRuleRepository = configRuleRepository;
            _unitOfWork = unitOfWork;
            _mapper = mapper;
        }

        public async Task<PaginatedResult<DataConfigInfoResponseDto>> QueryDataConfigsByPageAsync(DataConfigSearchRequestDto model)
        {
            var conditionCollection = new ConditionCollection();
            if (model != null)
            {
                var result =
                    await _dataConfigRepository.QueryFilterByOrderPageAsync(conditionCollection,
                        nameof(DataConfigEntity.Sort), "asc", model.Page, model.Limit);

                return await PaginatedResult<DataConfigInfoResponseDto>.SuccessAsync(
                    _mapper.Map<List<DataConfigInfoResponseDto>>(result.Item1),
                    result.Item2,
                    model.Page, model.Limit);
            }
            return await PaginatedResult<DataConfigInfoResponseDto>.SuccessAsync(
                new List<DataConfigInfoResponseDto>(), 0, 0, 0);
        }

        public async Task<Result<IList<DataConfigInfoResponseDto>>> QueryDatabasesAsync(DataConfigSearchRequestDto model)
        {
            var conditionCollection = new ConditionCollection();
            if (model != null)
            {

            }

            var result = await _dataConfigRepository.QueryFilterAsync(conditionCollection);
            return await Result<IList<DataConfigInfoResponseDto>>.SuccessAsync(
                _mapper.Map<List<DataConfigInfoResponseDto>>(result));
        }

        public async Task<Result<DataConfigInfoResponseDto>> GetDataConfigAsync(Guid id)
        {
            var dataBaseEntity = await _dataConfigRepository.GetAsync(id);
            return await Result<DataConfigInfoResponseDto>.SuccessAsync(
                _mapper.Map<DataConfigInfoResponseDto>(dataBaseEntity));
        }

        public async Task<Result<DataConfigInfoResponseDto>> CreateDataConfigAsync(DataConfigEditRequestDto model)
        {
            var dataBaseEntity = _mapper.Map<DataConfigEntity>(model);
            await _dataConfigRepository.InsertAsync(dataBaseEntity);

            _unitOfWork.Commit();

            return await Result<DataConfigInfoResponseDto>.SuccessAsync(
                _mapper.Map<DataConfigInfoResponseDto>(dataBaseEntity));
        }

        public async Task<Result<DataConfigInfoResponseDto>> UpdateDataConfigAsync(Guid id, DataConfigEditRequestDto model)
        {
            var dataBaseEntity = await _dataConfigRepository.GetAsync(id);

            if (dataBaseEntity != null)
            {
                _mapper.Map(model, dataBaseEntity);

                await _dataConfigRepository.UpdateAsync(dataBaseEntity);

                _unitOfWork.Commit();
            }

            return await Result<DataConfigInfoResponseDto>.SuccessAsync(
                _mapper.Map<DataConfigInfoResponseDto>(dataBaseEntity));
        }

        public async Task<PaginatedResult<ConfigFieldInfoResponseDto>> QueryFieldsByPageConfigAsync(string configCode, ConfigFieldSearchRequestDto model)
        {
            var result = await _configFieldRepository.QueryFieldsByPageConfigAsync(configCode, model);

            return await PaginatedResult<ConfigFieldInfoResponseDto>.SuccessAsync(
                _mapper.Map<List<ConfigFieldInfoResponseDto>>(result.Item1), result.Item2,
                model.Page, model.Limit);
        }

        public async Task<Result<ConfigFieldInfoResponseDto>> CreateFieldAsync(string configCode, ConfigFieldEditRequestDto model)
        {
            var dataConfigEntity = await _dataConfigRepository.GetByCodeAsync(configCode);

            var configFieldEntity = _mapper.Map<ConfigFieldEntity>(model);
            if (dataConfigEntity != null && (!string.IsNullOrEmpty(model.ControlType)))
            {
                var controlBase = ControlConfig.GetControl(model.ControlType);
                if (controlBase != null)
                {
                    var validationResult = controlBase.TryValidationCreatorControl(model);
                    var controlContent = validationResult.Item3.Serialize();

                    //await _configFieldRepository.QueryFilterAsync(new ConditionCollection()
                    //{
                    //   new ConditionDescriptor("ConfigId",dataConfigEntity.Id)
                    //});

                    configFieldEntity.ConfigId = dataConfigEntity.Id;
                    configFieldEntity.ControlContent = controlContent;
                    await _configFieldRepository.InsertAsync(configFieldEntity);

                    _unitOfWork.Commit();
                }
            }

            return await Result<ConfigFieldInfoResponseDto>
                .SuccessAsync(_mapper.Map<ConfigFieldInfoResponseDto>(configFieldEntity));
        }

        public async Task<Result<IList<ConfigFieldInfoResponseDto>>> QueryFieldsByConfigAsync(string configCode, ConfigFieldSearchRequestDto model)
        {
            var data = await _configFieldRepository.QueryFieldsByConfigAsync(configCode, model);

            var list = new List<ConfigFieldInfoResponseDto>();
            foreach (var field in data)
            {
                var item = _mapper.Map<ConfigFieldInfoResponseDto>(field);

                var controlBase = ControlConfig.GetControl(field.ControlType);
                if (controlBase != null)
                {
                    controlBase.Deserialize(field.ControlContent);
                    controlBase.BuildEditDefineValue(item);
                }
                list.Add(item);
            }
            return await Result<IList<ConfigFieldInfoResponseDto>>.SuccessAsync(list);
        }

        public async Task<Result<ConfigFieldInfoResponseDto>> GetConfigFieldAsync(Guid id)
        {
            var configFieldEntity = await _configFieldRepository.GetAsync(id);

            var item = _mapper.Map<ConfigFieldInfoResponseDto>(configFieldEntity);

            var controlBase = ControlConfig.GetControl(configFieldEntity.ControlType);
            if (controlBase != null)
            {
                controlBase.Deserialize(configFieldEntity.ControlContent);
                controlBase.BuildEditDefineValue(item);
            }

            return await Result<ConfigFieldInfoResponseDto>.SuccessAsync(item);
        }

        public async Task<Result<ConfigFieldInfoResponseDto>> UpdateFieldAsync(Guid id, ConfigFieldEditRequestDto model)
        {
            var configFieldEntity = await _configFieldRepository.GetAsync(id);

            if (configFieldEntity != null)
            {
                _mapper.Map(model, configFieldEntity);

                if (configFieldEntity != null && (!string.IsNullOrEmpty(model.ControlType)))
                {
                    var controlBase = ControlConfig.GetControl(model.ControlType);
                    if (controlBase != null)
                    {
                        var validationResult = controlBase.TryValidationCreatorControl(model);
                        var controlContent = validationResult.Item3.Serialize();

                        //await _configFieldRepository.QueryFilterAsync(new ConditionCollection()
                        //{
                        //   new ConditionDescriptor("ConfigId",dataConfigEntity.Id)
                        //});
                        configFieldEntity.ControlContent = controlContent;
                    }
                }

                await _configFieldRepository.UpdateAsync(configFieldEntity);

                _unitOfWork.Commit();
            }

            return await Result<ConfigFieldInfoResponseDto>.SuccessAsync(
                _mapper.Map<ConfigFieldInfoResponseDto>(configFieldEntity));
        }

        public async Task<PaginatedResult<ConfigRuleInfoResponseDto>> QueryRulesByPageConfigAsync(string configCode, ConfigRuleSearchRequestDto model)
        {
            var result = await _configRuleRepository.QueryRulesByPageConfigAsync(configCode, model);

            return await PaginatedResult<ConfigRuleInfoResponseDto>.SuccessAsync(
                _mapper.Map<List<ConfigRuleInfoResponseDto>>(result.Item1), result.Item2,
                model.Page, model.Limit);
        }

        public async Task<Result<IList<ConfigRuleInfoResponseDto>>> QueryRulesByConfigAsync(string configCode, ConfigRuleSearchRequestDto model)
        {
            var data = await _configRuleRepository.QueryRulesByConfigAsync(configCode, model);

            var list = new List<ConfigRuleInfoResponseDto>();
            foreach (var field in data)
            {
                var item = _mapper.Map<ConfigRuleInfoResponseDto>(field);

                //var controlBase = ControlConfig.GetControl(field.ControlType);
                //if (controlBase != null)
                //{
                //    controlBase.Deserialize(field.ControlContent);
                //    controlBase.BuildEditDefineValue(item);
                //}
                list.Add(item);
            }
            return await Result<IList<ConfigRuleInfoResponseDto>>.SuccessAsync(list);
        }

        public Task<Result<ConfigRuleInfoResponseDto>> CreateRuleAsync(string configCode, ConfigRuleEditRequestDto model)
        {
            throw new NotImplementedException();
        }
    }
}